package com.cavy.platform.client.service;

import com.cavy.platform.client.message.HeartbeatMessage;
import com.cavy.platform.client.message.JobDispatcher;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import sun.misc.Signal;
import sun.misc.SignalHandler;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import java.util.ArrayList;
import java.util.List;

/**
 * @author 唐旭
 * @Date 2018/7/26
 */
@Service
@Slf4j
public class HeartbeatService implements Runnable, SignalHandler {
    private static final int INTERVAL = 2000;
    private final Thread thread = new Thread(this);
    private volatile boolean run = true;
    @Autowired
    private WebSocketService webSocketService;
    @Autowired
    private SystemInfoService infoService;
    @Autowired
    private JobDispatcher dispatcher;
    @Autowired
    private List<AgentClose> closeList = new ArrayList<>();

    @PostConstruct
    public void init() {
        thread.setName("Heartbeat");
        log.debug("心跳线程已启动...");
    }

    @PreDestroy
    public void destroy() throws InterruptedException {
        synchronized (this) {
            run = false;
        }
        if (thread.isAlive()) {
            thread.join(1000);
        }
    }

    @Override
    public void run() {
        try {
            while (run) {
                heartbeat();
                Thread.sleep(INTERVAL);
            }
        } catch (InterruptedException e) {
            log.error(e.getMessage());
            e.printStackTrace();
            thread.interrupt();
        }
    }

    private void heartbeat() {
        HeartbeatMessage message = new HeartbeatMessage();
        message.setJobCount(dispatcher.currentJobCount());
        message.setMemoryUsed(infoService.getFreeMemory());
        webSocketService.send(message);
        log.debug("已发送心跳...");
    }

    public void join() throws InterruptedException {
        thread.join();
    }

    public void start() {
        thread.start();
    }

    @Override
    public void handle(Signal signal) {
        log.warn("正在结束agent...");
        try {
            //关闭各组件
            closeService();
            //停止心跳
            destroy();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    private void closeService() {
        for (AgentClose item : closeList) {
            item.close();
        }
    }
}
